/* eslint-disable no-undef */
/* eslint-disable import/no-webpack-loader-syntax */
// 把script-loader file-loader 引入进来
import XLSX from 'xlsx'
require('script-loader!file-saver');

// 时间处理方法
function dateNum(cell, date1994) {
    if (date1994) cell += 1462
    let epoch = Date.parse(cell)
    return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000)
}
// 工作流
function WorkHook() {
    if (!this instanceof WorkHook) return new WorkHook();
    this.SheetNames = [];
    this.Sheets = {};
}
// 过滤data 方法
function sheet_from_array_of_arrays(data, opts) {
    var ws = {};
    var range = {
      s: {
        c: 10000000,
        r: 10000000
      },
      e: {
        c: 0,
        r: 0
      }
    };
    for (var R = 0; R !== data.length; ++R) {
      for (var C = 0; C !== data[R].length; ++C) {
        if (range.s.r > R) range.s.r = R;
        if (range.s.c > C) range.s.c = C;
        if (range.e.r < R) range.e.r = R;
        if (range.e.c < C) range.e.c = C;
        var cell = {
          v: data[R][C]
        };
        if (cell.v == null) continue;
        var cell_ref = XLSX.utils.encode_cell({
          c: C,
          r: R
        });

        if (typeof cell.v === 'number') cell.t = 'n';
        else if (typeof cell.v === 'boolean') cell.t = 'b';
        else if (cell.v instanceof Date) {
          cell.t = 'n';
          cell.z = XLSX.SSF._table[14];
          cell.v = dateNum(cell.v);
        } else cell.t = 's';

        ws[cell_ref] = cell;
      }
    }
    if (range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range);
    return ws;
  }

// 进制转化方法
function s2ab(wbout) {
    let buf = new ArrayBuffer(wbout.length)
    let view = new Uint8Array(buf);
    for (let i = 0; i != wbout.length; ++i) {
        view[i] = wbout.charCodeAt(i) & 0xFF;
    }
    return buf
}

export function export_json_to_excel({
    multHeader = [],
    header,
    data,
    filename,
    merges = [],
    autoWidth = true,
    bookType = 'xlsx'
} = {}) {
    filename = filename || 'excel-list'
    data = [...data]
    data.unshift(header)

    for (let i = multHeader.length - 1; i > -1; i--) {
        data.unshift(multHeader[i])
    }

    let ws_name = 'SheetJS'
    // let  定义工作流 workHook
    let wb = new WorkHook();
    // 需要过滤data
    let ws = sheet_from_array_of_arrays(data);

    if (merges.length > 0) {
        if (!ws['!merges']) ws['!merges'] = [];
        merges.forEach(item => {
            ws['!merges'].push(XLSX.utils.decode_range(item))
        })
    }

    if (autoWidth) {
        // 设置worksheet每列最大的宽度
        const colWidth = data.map(row => row.map(val => {
            if (val == null) {
                return {
                    'wch': 10
                }
                // 再判断是否为中文
            } else if (val.toString().charCodeAt(0) > 255) {
                return {
                    'wch': val.toString().length * 2
                }
            } else {
                return {
                    'wch': val.toString().length
                }
            }
        }))
        let result = colWidth[0];
        for (let i = 1, l = colWidth.length; i < l; i++) {
            for (let j = 0, jl = colWidth[i].length; j < jl; j++) {
                if (result[j]['wch'] < colWidth[i][j]['wch']) {
                    result[j]['wch'] = colWidth[i][j]['wch']
                }
            }
        }
        ws['!col'] = result;
    }
    // 需要把工作表 加到 workhook
    wb.SheetNames.push(ws_name);
    wb.Sheets[ws_name] = ws;

    let wbout = XLSX.write(wb, {
        bookType,
        bookSST: false,
        type: 'binary'
    })
    // 会用到声明的一个方法，会进制转化
    saveAs(new Blob([s2ab(wbout)], {
        type: "application/octet-stream"
    }), `${filename}.${bookType}`);
}